package com.example.number1.ui.theme;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;

import androidx.annotation.Nullable;

import com.example.number1.R;

import java.util.ArrayList;
import java.util.List;

public class MyTextView extends View {

    private int mSpeed;
    private Paint mPaint;
    private Rect mTextBounds;
    private String Text;
    private float mOffsetX;
    private float mTextWidth;
    //显示文本
    private String mText;
    private Context mContext;
    //文本字体大小
    private int mTextSize;
    //文本颜色
    private int mTextColor;
    //文本对齐方式
    private int mGravity = Gravity.TOP | Gravity.START;
    //控件背景
    private int mBackgroud;
    //文本最大行数
    private int mMaxLines;
    //控件左内边距
    private int mPaddingStart;
    //控件右内边距
    private int mPaddingEnd;
    //文本画笔
    private Paint mTextPaint;
    //背景画笔
    private Paint backgroudPaint;
    private Paint measureTextPaint;
    private Rect mTextRect;
    private int width;
    private int height;
    private int lineNum;
    private List<String> txtList;
    private int heightOfLine;
    private int linespacingextra;
    private boolean singleline;
    private boolean marquee;
    private int marqueerepeatlimitt;

    public MyTextView(Context context) {
        this(context,null);
    }

    public MyTextView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr,0);
    }

    public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        mContext = context;
        init(attrs);
    }

    private void init(AttributeSet attrs) {
        //获取属性文件，并加载所有的自定义属性集合ta
        TypedArray ta = mContext.obtainStyledAttributes(attrs,R.styleable.MyTextView);

        //获取相应的属性，文本
        mText = ta.getString(R.styleable.MyTextView_text);
        //获取相应的属性，字体大小
        mTextSize = ta.getDimensionPixelSize(R.styleable.MyTextView_textSize,15);
        //获取相应的属性，行数
        mMaxLines = ta.getInt(R.styleable.MyTextView_maxLines, Integer.MAX_VALUE);
        //获取相应的属性，边距
        mPaddingStart = getPaddingStart();
        //获取相应的属性，边距
        mPaddingEnd = getPaddingEnd();
        ta.getInt(R.styleable.MyTextView_gravity, 1-4);
        //行间距
      //  linespacingextra = ta.getInt(R.styleable.MyTextView_linespacingextra,Integer.MAX_VALUE);
        //单行
        singleline = ta.getBoolean(R.styleable.MyTextView_singleline, true);
        //跑马灯效果
        marquee = ta.getBoolean(R.styleable.MyTextView_marquee, true);
        //跑马灯次数
        marqueerepeatlimitt = ta.getInt(R.styleable.MyTextView_marqueerepeatlimit, Integer.MAX_VALUE);

        //循环
        ta.recycle();

        //创建画笔
        mTextPaint = new Paint();
        //字体的大小
        mTextPaint.setTextSize(mTextSize);
        //字体的颜色默认为黑色
        mTextPaint.setColor(Color.GREEN);
        //创建一个矩形，并且所有坐标都为0
        mTextRect = new Rect();
        //用笔描绘矩形的大小
        mTextPaint.getTextBounds(mText,0,mText.length(),mTextRect);
        backgroudPaint = new Paint();
        //背景为红色
        backgroudPaint.setColor(Color.RED);
        measureTextPaint = new Paint();
        txtList = new ArrayList<>();


        //跑马灯
        mPaint.setTextSize(getResources().getDimensionPixelSize(R.dimen.marquee_text_size));
        mPaint.setColor(getResources().getColor(R.color.marquee_text_color));
        mTextBounds = new Rect();

    }

    /**
     * 简单来说就是把组件算一下有多大，然后在onDraw（）方法中进行具体的绘画出来
     *
     *
     * 测量控件的大小，当我们创建一个View(执行构造方法)的时候不需要测量控件的大小，
     * 只有将这个view放入一个容器（父控件）中的时候才需要测量，而这个测量方法就是父控件唤起调用的。
     * @param widthMeasureSpec horizontal space requirements as imposed by the parent.
     *                         The requirements are encoded with
     *                         {@link MeasureSpec}.
     * @param heightMeasureSpec vertical space requirements as imposed by the parent.
     *                         The requirements are encoded with
     *                         {@link MeasureSpec}.
     *
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        Log.e("MyTextView", "widthMode: "+widthMode);
        Log.e("MyTextView", "widthSize: "+widthSize);
        Log.e("MyTextView", "heightMode: "+heightMode);
        Log.e("MyTextView", "heightSize: "+heightSize);
        width = widthSize;
        height = heightSize;
        if(widthMode == MeasureSpec.AT_MOST){
            Log.e("MyTextView","width:"+width+",textwidth:"+mTextRect.width());
            if(width >= mTextRect.width() + mPaddingEnd+mPaddingStart){//one line
                width = mTextRect.width()+mPaddingEnd+mPaddingStart;
                txtList.add(mText);
                lineNum = 1;
            }else{//more lines
                float num = (float) mTextRect.width()/(width-mPaddingStart-mPaddingEnd);
                lineNum = num == (int)num ? (int)num : (int)num+1;
                Log.e("MyTextView", "num: "+num );
                measureTextPaint.setTextSize(mTextSize);
                int len = mText.length();
                float currlen = 0;
                String txt = null;
                for(int i = 0,start = 0;i<lineNum;i++){
                    Log.e("MyTextView", "start "+start);
                    int j = 1;
                    while(currlen < width - mPaddingEnd-mPaddingStart&& start + j<mText.length()-1){
                        txt = mText.substring(start,start+j++);
                        Log.e("MyTextView",txt);
                        currlen = measureTextPaint.measureText(txt);
                    }
                    txtList.add(txt);
                    start += txt.length();
                    txt = null;
                    currlen = 0;
                }
            }
        }
        if(heightMode == MeasureSpec.AT_MOST){
            Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
            float top = fontMetrics.top;
            float bottom = fontMetrics.bottom;
            heightOfLine = (int)(bottom - top);
            if(lineNum == 1){
                height = heightOfLine;
            }else{
                height = heightOfLine*Math.min(lineNum,mMaxLines);
            }

        }
        setMeasuredDimension(width,height);


        if (Text != null) {
            mPaint.getTextBounds(Text, 0, Text.length(), mTextBounds);
            mTextWidth = mTextBounds.width();
            int textHeight = mTextBounds.height();
            setMeasuredDimension((int) mTextWidth, textHeight);
        } else {
            setMeasuredDimension(0, 0);
        }
    }

    /**
     * onDraw是绘制控件的方法，绘制的内容和该方法的参数canvas（画布）息息相关
     * 下面是画布的一些方法
     * canvas.drawColor();绘制背景，用于初始化和清空画布
     * canvas.drawRGB();
     * canvas.drawRect();绘制矩形
     * canvas.drawRoundRect();绘制圆角矩形
     * canvas.drawCircle();绘制圆形
     * canvas.drawPath();绘制路径
     * canvas.drawLine();绘制线条
     * canvas.drawArc();绘制圆弧
     * canvas.drawOval();绘制椭圆
     * canvas.drawPoint();绘制点
     * canvas.drawPoints();
     * canvas.drawText();绘制文本
     * canvas.drawTextOnPath();沿路径绘制文本
     * canvas.drawBitmap();绘制bitmap
     * @param canvas the canvas on which the background will be drawn
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (Text != null) {
            canvas.drawText(Text, -mOffsetX, getHeight() / 2 + mTextBounds.height() / 2, mPaint);
        }

        Log.e("MyTextView","linenum:"+lineNum);
        Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
        float top = fontMetrics.top;
        Log.e("MyTextView", "top: "+top );
        canvas.drawRect(0,0,width,height,backgroudPaint);
        for(int i = 0; i<Math.min(lineNum,mMaxLines); i++){
            canvas.drawText(txtList.get(i),mPaddingStart,-top,mTextPaint);
            canvas.translate(0,heightOfLine);
            if(i == mMaxLines){
                measureTextPaint.setTextSize(mTextSize);
                float v = measureTextPaint.measureText("...");
                int currlen;
            }
        }
    }


    public void startMarquee() {
        if (mText != null && mTextWidth > getWidth()) {
            post(new Runnable() {
                @Override
                public void run() {
                    mOffsetX += mSpeed;
                    invalidate();
                    if (-mOffsetX >= mTextWidth) {
                        mOffsetX = 0;
                        postDelayed(this, 1000);
                    } else {
                        postDelayed(this, 16);
                    }
                }
            });
        }
    }

    public void setText(String text) {
        mText = text;
        invalidate();
    }
}
